import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
from sklearn.preprocessing import StandardScaler, MinMaxScaler

df=pd.read_csv('../DATA/北京二手房.csv',thousands=",")

print('前十条数据是：')
print(df.head(10))
print('后十条数据是：')
print(df.tail(10))


# 数据格式化
df["建房年份"]=pd.to_datetime(df["建房年份"],format='%Y')

# 显示数据集的基本信息
print("数据集的基本信息：")
print(df.info())




# 提供数据集的描述性统计信息
print("数据集的描述性统计信息：")
print(df.describe())

print(df.head(40))

# 显示不是数值类型的数据信息
print("不是数值类型的数据信息：")
print(df.select_dtypes(exclude=['number']))

# 返回不是空值的数据信息
print("不是空值的数据信息：")
print(df.dropna())


# 去重
duplicates = df[df.duplicated()]
print("重复值：")
print(duplicates)
print('可见无重复值')


# 处理缺失值
null_columns = df.columns[df.isnull().any()]
print("缺失值的信息：")
print(null_columns)
fill_date=pd.to_datetime("2000-01-01")#特殊值填充
df["建房年份"].fillna(fill_date,inplace=True)
# print(df.head(5))
df['建房年份'].fillna(method='ffill',inplace=True)#前填充
df['建房年份'].fillna(method='bfill',inplace=True)#后填充
print(df.head(40))


# 异常值监测
# 检查“总价”和“每平方米价格”列是否符合正态分布
for column in ['总价', '平米单价']:
    # 执行Shapiro-Wilk正态性检验
    statistic, p_value = stats.shapiro(df[column])
    #statistic: 这是Shapiro-Wilk检验的统计量，用于衡量数据与正态分布的偏离程度。统计量的值越接近1，表明数据越接近正态分布。
    # 如果p_value大于显著性水平（例如0.05），则认为数据符合正态分布
    if p_value > 0.05:
        # 找到大于三倍标准差的数据项
        outliers = df[column][(df[column] > df[column].mean() + 3 * df[column].std()) |
                                (df[column] < df[column].mean() - 3 * df[column].std())]
        # print(f"{column}符合正态分布，异常值为：{outliers}")
    else:
        # 计算四分位数和IQR
        Q1 = df[column].quantile(0.25)
        Q3 = df[column].quantile(0.75)
        IQR = Q3 - Q1
        # 找到大于Q3 + 1.5*IQR和小于Q1 - 1.5*IQR的数据项
        outliers = df[column][(df[column] > Q3 + 1.5 * IQR) |
                                (df[column] < Q1 - 1.5 * IQR)]
        # print(f"{column}不符合正态分布，异常值为：\n{outliers}")
        mode = df[column].mode().iloc[0]#获取众数
        df[column] = df[column].replace(outliers.index, mode)#替换异常值为众数
        modified_items = df[column][df[column] == mode]
        # print(f"被修改的数据项（替换为众数）：\n{modified_items}")

# 数据格式化
df["建房年份"]=pd.to_datetime(df["建房年份"],format='%Y')
df['总价']=df['总价'].astype(float)
df['平米单价']=df['平米单价'].astype(float)
# pd.set_option('display.max_columns', None)
# print(df.head(20))
# print(df.info())

#数据归一化
print("处理前的数据:")
print(df['总价'])
column_to_scale='总价'
# 标准化处理
scaler = StandardScaler()
df[column_to_scale + '_standardized'] = scaler.fit_transform(df[[column_to_scale]])
# 输出标准化处理后的数据
print("标准化处理后的数据:")
print(df[column_to_scale + '_standardized'])

# 归一化处理
scaler = MinMaxScaler()
df[column_to_scale + '_normalized'] = scaler.fit_transform(df[[column_to_scale]])

# 输出归一化处理后的数据
print("归一化处理后的数据:")
print(df[column_to_scale + '_normalized'])


# 图表展示

plt.rcParams['font.sans-serif'] = ['KaiTi']
# 假设CSV文件中有一个名为'price_per_unit'的列表示单价，'area'的列表示面积
price_per_unit = df['平米单价']
area = df['面积']

# 创建散点图
plt.figure(figsize=(10, 6))
plt.scatter(area, price_per_unit, color='blue', alpha=0.5)
plt.title('房屋单价与面积关系',fontsize=40)
plt.xlabel('面积（平方米）',fontsize=40)
plt.ylabel('单价（元/平方米）',fontsize=40)

# 显示图表
plt.show()


df.to_csv("清洗完毕的数据.csv",index=False)


